/**
 * @addtogroup sfc_xbus
 * sfc_xbus
 * @{
 */
/**
 * @file         sfc_xbus.h
 * @brief        消息通信总线
 * @note    
 * @author       Akee(ysk@hopechart.com)
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-09-15  <td>1.0                   <td>Akee            <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _SFC_XBUS_H_
#define _SFC_XBUS_H_

#include "ofc/ofc_types.h"

#include "hcc/hcc_error_code.h"
#include "hcc/hcc_error_code_mod.h"
#include "hcc/hcc_error_code_mid_xbus.h"


#ifdef __cplusplus
extern "C" {
#endif

/**
 * 
 */
typedef struct TSfXbusLogMsgTag TSfXbusLogMsg;
struct TSfXbusLogMsgTag
{
    Int8 *log;
};

typedef void(*SfXbusDoLogNotify)(void *sender, TSfXbusLogMsg *log_msg);

/**
 * 消息总线项类型
 */
typedef struct TSfXbusMsgItemTypeTag TSfXbusMsgItemType;
struct TSfXbusMsgItemTypeTag
{
    UInt16 msg_id;          ///< 消息id
    UInt8 param[6];         ///< 参数
};

typedef struct TSfXbusMsgGroupItemTag TSfXbusMsgGroupItem;
struct TSfXbusMsgGroupItemTag
{
    UInt16 group_id;          ///< 消息Id
#ifdef __linux__	
    UInt32 group_index_flag;      ///< 组标记
#else
    UInt16 group_index_flag;      ///< 组标记	
#endif
};


/**
 * 
 */
typedef struct TSfXbusMsgExtAttrTag TSfXbusMsgExtAttr;
struct TSfXbusMsgExtAttrTag
{
    UInt32 tick;    
};



/**
 * 消息总线项类型
 */
typedef struct TSfXbusMsgItemRecvTypeTag TSfXbusMsgItemRecvType;
struct TSfXbusMsgItemRecvTypeTag
{
    TSfXbusMsgItemType msg_item; ///< 消息
    TSfXbusMsgExtAttr ext_attr;
    UInt8 queue_index_flag;
    UInt8 msg_type;                ///< 消息类型，参考 @ref TSfXbusMsgTypeEnum
    //UInt8 private_data[24];      ///< 私有数据
};

/**
 * 消息总线的消息类型
 */
enum TSfXbusMsgTypeEnumTag
{
    kSfXbusMsgTypePost       = 0,    ///< 消息投递,不阻塞
    kSfXbusMsgTypeSend       = 1,    ///< 消息发送,阻塞
};
typedef enum TSfXbusMsgTypeEnumTag TSfXbusMsgTypeEnum;



/**
 * 构造函数
 * @param self: 对象指针
 * @return 
 */
void TSfXbusMsgExtAttrCreate(TSfXbusMsgExtAttr *self);

/**
 * 析构函数
 * @param self: 对象指针
 * @return 
 */
void TSfXbusMsgExtAttrDestroy(TSfXbusMsgExtAttr *self);

/**
 * 消息总线标志枚举
 */
enum TSfXbusFlagEnumTag
{
    kSfXbusFlagLimitNotRecordLog = (0 << 0),    ///< 高水位不写日志
    kSfXbusFlagLimitRecordLog    = (1 << 0),    ///< 高水位写日志

    kSfXbusFlagTimeoutLevel1     = (0 << 1),    ///< 超时时间10秒
    kSfXbusFlagTimeoutLevel2     = (1 << 1),    ///< 超时时间300秒
    kSfXbusFlagTimeoutLevel3     = (2 << 1),    ///< 超时时间3600秒
    kSfXbusFlagTimeoutLevel4     = (3 << 1),    ///< 超时时间86400秒

    kSfXbusFlagMsgRepeatNotDiscard = (0 << 3),  ///< 重复不可丢弃
    kSfXbusFlagMsgRepeatDiscard  = (1 << 3),    ///< 重复可丢弃

    kSfXbusFlagMsgNotPersistent  = (0 << 4),    ///< 允许丢弃数据
    kSfXbusFlagMsgPersistent     = (1 << 4),    ///< 不允许丢弃数据
};
typedef enum TSfXbusFlagEnumTag TSfXbusFlagEnum;


/**
 * 消息等级时间
 */
enum TSfXbusMsgTimeLevelEnumTag
{
    kSfXbusMsgTimeL0ms = 0,
    kSfXbusMsgTimeL50ms = 1,
    kSfXbusMsgTimeL500ms = 2,
    kSfXbusMsgTimeL1000ms = 3,
    kSfXbusMsgTimeL2000ms = 4,
    kSfXbusMsgTimeL5000ms = 5,
    kSfXbusMsgTimeLCount,
};
typedef enum TSfXbusMsgTimeLevelEnumTag TSfXbusMsgTimeLevelEnum;

/**
 * 消息总线初始化
 * @return 参考 @ref THccMidXbusErrorCode
 * @note 需要在操作系统启动后再初始化
 */
Int32 SfXbusInit(void *do_log_object, SfXbusDoLogNotify do_log_method);

/**
 * 消息总线去初始化
 * @return 参考 @ref THccMidXbusErrorCode
 * @note 会把所有的消息队列总线全部关闭
 */
void SfXbusDone(void);

/**
 * 消息总线打开
 * @param bus_id: 需要创建的总线id
 * @param total_capacity: 总线id占用的队列容量
 * @param alert_capacity: 警戒容量
 * @return 参考 @ref THccMidXbusErrorCode
 */
Int32 SfXbusOpen(Int32 bus_id, UInt8 total_capacity, UInt8 alert_capacity);

/**
 * 消息总线关闭
 * @param bus_id: 需要关闭的总线id
 * @return
 * @note 关闭后所有除kSfXbusFlagMsgPersistent的消息全部丢弃
 */
void  SfXbusClose(Int32 bus_id);

/**
 * 消息总线发送参数,内部不阻塞,表示仅丢到队列中
 * @param dst_bus_id: 目标总线id
 * @param msg_item_type: 发送的消息数据
 * @param flag: 参考TSfXbusFlagEnum,默认填写0即可
 * @return <0: 参考 @ref THccMidXbusErrorCode
 */
Int32 SfXbusPostMsg(Int32 dst_bus_id, const TSfXbusMsgItemType *msg_item_type, Int32 flag);

/**
 * 消息总线发送消息,内部阻塞,需对方接收后正常处理并反馈接口才会返回
 * @param dst_bus_id: 目标总线id
 * @param msg_item_type: 发送的消息数据
 * @param flag: 参考TSfXbusFlagEnum
 * @param time_level: 时间等级，表示等待时长
 * @return <0: 参考 @ref THccMidXbusErrorCode, >0 表示对方的结果值
 * @note 此接口为阻塞
 */
Int32 SfXbusSendMsg(Int32 dst_bus_id, const TSfXbusMsgItemType *msg_item_type, Int32 flag, TSfXbusMsgTimeLevelEnum time_level);

/**
 * 消息总线获取消息,等待结果
 * @param dst_bus_id: 目标总线id
 * @param msg_item_type: 消息
 * @param time_level: 时间等级
 * @param ext_attr: 附加属性，暂未实现，传NULL表示不关心,仅当结果为成功时有效
 * @return <0: 参考 @ref THccMidXbusErrorCode
 */
Int32 SfXbusGetMsg(Int32 dst_bus_id, TSfXbusMsgItemRecvType *msg_item_type, TSfXbusMsgTimeLevelEnum time_level, TSfXbusMsgExtAttr **ext_attr);

/**
 * 消息总线应答消息
 * @param dst_bus_id: 目标总线id
 * @param msg_item_type: 消息
 * @param resp_result: 应答结果
 * @return <0: 参考 @ref THccMidXbusErrorCode
 */
Int32 SfXbusResponseMsg(Int32 dst_bus_id, TSfXbusMsgItemRecvType *msg_item_type, Int32 resp_result);

/**
 * 设置消息总线组
 * @param msg_group: 消息总线组
 * @return <0: 参考 @ref THccMidXbusErrorCode
 * @note 末尾以0,0结尾
 * @par 代码示例
 * @code
    TSfXbusMsgGroupItem g_xbus_msg_group[] =
    {
        {4098, 0x0003},
        {0x0002, 0x0003},
        {9999, 0x00F6},
        {0x0000, 0x0000},
    };

    SfXbusSetMsgGroup(g_xbus_msg_group);
 * @endcode
 */
Int32 SfXbusSetMsgGroup(TSfXbusMsgGroupItem *msg_group);

#ifdef __cplusplus
} // extern "C" {
#endif

#endif

/**
 * @} 
 */
 
 
 



